package com.cqut.service.impl;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.cqut.service.IMenuService;
import com.cqut.model.Menu;
import com.cqut.dao.MenuMapper;
import com.cqut.dao.MenuMapperExtra;
import com.cqut.dto.LimitShowDTO;
import com.cqut.dto.MenuDTO;
import com.cqut.util.BeanUtil;
import com.cqut.util.SqlUtil;
import com.cqut.util.StringUtil;
import com.cqut.util.SystemConstants;
import com.scienjus.authorization.annotation.Authorization;

@Service
public class MenuService implements IMenuService {
    @Resource(name="menuMapper")
    private MenuMapper menuMapper;
    
    @Resource(name="menuMapperExtra")
    private MenuMapperExtra menuMapperExtra;

    @Override
    public boolean save(Menu menu) {
        return menuMapper.insert(menu) > 0;
    }

    @Override
    public boolean update(Menu menu) {
        return menuMapper.updateByPrimaryKeySelective(menu) >= 0;
    }

    @Override
    public boolean delete(String menuId) {
        return menuMapper.deleteByPrimaryKey(menuId) > 0;
    }
 
    @Override
    public boolean batchDelete(String[] primaryKeys) {
        return menuMapper.deleteByPrimaryKeys(primaryKeys) > 0;
    }

    @Override
    public Menu findModel(String menuId) {
        return menuMapper.selectByPrimaryKey(menuId);
    }

    @Override
    public Menu findModel(String menuId, String[] parameters) {
        return menuMapper.findModel(menuId, SqlUtil.formatParameters(parameters));
    }

    public Map<String, Object> findMap(String menuId) {
        String[][] parameters = {{"menu_id", "menuId"}, {"menu_name", "menuName"}, {"up_id", "upId"}, {"level", "level"}, {"path", "path"}, {"order_no", "orderNo"}, {"remark", "remark"}};
        return this.findMap(menuId, parameters);
    }

    public Map<String, Object> findMap(String menuId, String[][] parameters) {
        return menuMapper.findMap(menuId, SqlUtil.formatParametersForAlias(parameters));
    }

    @Override
    public List<Menu> loadModels() {
        return this.loadModels(null, null, null, null, -1, -1);
    }

    @Override
    public List<Menu> loadModels(String condition, Object[] values, String order, String sort, int curPage, int limit) {
        return this.loadModels(null, condition, values, order, sort, curPage, limit);
    }

    @Override
    public List<Menu> loadModels(String[] parameters, String condition, Object[] values, String order, String sort, int curPage, int limit) {
        return menuMapper.loadModels(SqlUtil.formatParameters(parameters), SqlUtil.fillCondition(condition, values), order, sort, SqlUtil.getOffset(curPage, limit), limit);
    }

    @Override
    public List<Map<String, Object>> loadMaps() {
        String[][] parameters = {{"menu_id", "menuId"}, {"menu_name", "menuName"}, {"up_id", "upId"}, {"level", "level"}, {"path", "path"}, {"order_no", "orderNo"}, {"remark", "remark"}};
        return this.loadMaps(parameters, null, null, null, null, -1, -1);
    }

    @Override
    public List<Map<String, Object>> loadMaps(String condition, Object[] values, String order, String sort, int curPage, int limit) {
        String[][] parameters = {{"menu_id", "menuId"}, {"menu_name", "menuName"}, {"up_id", "upId"}, {"level", "level"}, {"path", "path"}, {"order_no", "orderNo"}, {"remark", "remark"}};
        return this.loadMaps(parameters, condition, values, order, sort, curPage, limit);
    }

    @Override
    public List<Map<String, Object>> loadMaps(String[][] parameters, String condition, Object[] values, String order, String sort, int curPage, int limit) {
        return menuMapper.loadMaps(SqlUtil.formatParametersForAlias(parameters), SqlUtil.fillCondition(condition, values), order, sort, SqlUtil.getOffset(curPage, limit), limit);
    }

    @Override
    public long count() {
        return this.count(null, false);
    }

    @Override
    public long count(String condition, Object[] values) {
        return this.count(null, condition, values, false);
    }

    @Override
    public long count(String[] parameters, boolean isDistinct) {
        return this.count(parameters, null, null, isDistinct);
    }

    @Override
    public long count(String[] parameters, String condition, Object[] values, boolean isDistinct) {
        return menuMapper.count(SqlUtil.formatParameters(parameters), SqlUtil.fillCondition(condition, values), isDistinct);
    }
    
   
    /**
     * 得到初始模块列表条数
     */
    @Override
    public long getLoadListCount(Menu menu, LimitShowDTO limitShowDTO){
    	return menuMapperExtra.getLoadListCount(menu.getMenuId(),menu.getLevel(),limitShowDTO.calculateStart(),limitShowDTO.calculateEnd());
    }
    /**
     * 根据搜索模块名进行筛选
     * @param moduleName
     * @param limitShowDTO
     * @return
     */
    @Override
	public List<Map<String, Object>> findModules(String moduleName,
			LimitShowDTO limitShowDTO) {
		return menuMapperExtra.findModules(moduleName,limitShowDTO.calculateStart(), limitShowDTO.calculateEnd());
	}
    
    /**
	 * 模块新增
	 */
	@Override
	public boolean addModule(MenuDTO menuDTO) {
		if (StringUtil.isNullOrEmpty(menuDTO.getUpId()))//判断父亲节点，此处数据结构设计师以id为节点使用
			menuDTO.setUpId(null);
		
		//通过upId来找到最大menuId
		Map<String, Object> maxCode = menuMapperExtra.findMaxCodeByParentCode(menuDTO.getUpId());
		
		Menu module = menuDTO.toModel();
		module.setIsShow(menuDTO.getIsShow());
		module.setPath(menuDTO.getPath());
		module.setUpId(menuDTO.getUpId());
		module.setMenuName(menuDTO.getMenuName());
		if(maxCode !=null && !maxCode.isEmpty())		
			module.setMenuId(BeanUtil.getTreeCode(maxCode.get("maxCode").toString()));   //生成一个menuId
		else
			module.setMenuId(BeanUtil.getTreeCodeForInit(menuDTO.getUpId()));
		//module.setHasChild(SystemConstants.FALSE_0);
		
		//生成层级
		int level = creatLevel0(menuDTO.getUpId());
		module.setLevel(level);
		//生成是否有孩子
		//module.setHasChild((byte)0);
		int newOrder = getMaxShowOrder(menuDTO.getUpId());
		module.setOrderNo(newOrder);
		if(menuMapper.insertSelective(module)<=0)
			return false;
		//setParentHasChild(menuDTO.getUpId(), (byte) 1);此处是修改父亲是否有孩子，单该数据结构并未涉及到该字段
		return true;
	}
    
	/**
	 * 新增的时候寻找最大的序号
	 */
	private int getMaxShowOrder(String parent){
		int num = 0;
		Map<String, Object> findOrder = menuMapperExtra.findModule(parent);
		if(findOrder != null && !findOrder.isEmpty())
			num = Integer.parseInt(findOrder.get("showOrder").toString())+1;
		
		return num;
	}
	
	/**
	 * 根据upId生成level0
	 * */
	@Authorization
	private int creatLevel0(String upId) {
		if(upId==null ||upId.trim().equals(""))
			return 0;		
		String level0 = (String) menuMapperExtra.selectLevel0(upId);
		return Integer.parseInt(level0) + 1 ;
	}
	
    /**
	 * 判断模块名是否重复
	 * */
	@Override
	public boolean judgeRepition(String moduleName) {
		if(moduleName==null||moduleName=="")
			return false;
		if (menuMapperExtra.judgeRepition(moduleName) == null || ((Map<String, Object>) menuMapperExtra.judgeRepition(moduleName)).size() == 0)
			return true;
		
		return false;
	}
	
	
	/**
	 * 模块列表中数据上移
	 */
	
	public boolean moveUp(int orderNo,String menuId,String upId){
		if (StringUtil.isNullOrEmpty(upId))
			upId = null;
		
		Map<String, Object> biggerData = menuMapperExtra.findBigger(orderNo,upId);  //找到比当前模块大且最接近当前模块的orderNo;
		if(biggerData == null || biggerData.isEmpty())
			return false;
		
		return swapShowOrder(menuId,orderNo,biggerData.get("menu_id").toString(),Integer.parseInt(biggerData.get("order_no").toString()));
	}
	
	/**
	 * 交换需要上移或下移的两个showOrder的值
	 */
	@Authorization
	private boolean swapShowOrder(String id, int showOrder, String otherId,
			int otherShowOrder) {
		Menu menu = getModuelForShowOrder(id, otherShowOrder);  //交换两个模块的orderNo
		Menu otherModule = getModuelForShowOrder(otherId, showOrder);
		
		//更新两个模块的orderNo
		return menuMapper.updateByPrimaryKeySelective(menu) > 0   
				&& menuMapper.updateByPrimaryKeySelective(otherModule) > 0;
	}
	
	private Menu getModuelForShowOrder(String id, int showOrder) {
		Menu menu = new Menu();
		menu.setMenuId(id);
		menu.setOrderNo(showOrder);
		
		return menu;
	}
	
	/**
	 * 模块列表中数据下移
	 */
	@Override
	public boolean moveDown(int showOrder, String id, String parentCode) {
		if (StringUtil.isNullOrEmpty(parentCode))
			parentCode = null;
		
		Map<String, Object> smallerData = menuMapperExtra.findSmaller(showOrder,parentCode);
		if(smallerData == null || smallerData.isEmpty())
			return false;
		return swapShowOrder(id,showOrder,smallerData.get("menu_id").toString(),Integer.parseInt(smallerData.get("order_no").toString()));
	}

	/**
	 * 进入下一级目录
	 */
	@Override
	public List<Map<String, Object>> goNextCatalog(String parentCode,LimitShowDTO limitShowDTO){
		List<Map<String,Object>> modules = menuMapperExtra.goNextPage(parentCode, limitShowDTO.calculateStart(), limitShowDTO.calculateEnd());
		System.out.println(modules);
		if (modules.size() > 0) {
			return modules;
		} else {
			return null;
		}
	}
	
	/**
	 * 查找模块的数量
	 */
	@Override
	public Object findCountOfModules(String moduleName,String parentCode) {
		List<Map<String, Object>> modules = 
				menuMapperExtra.findModulesWithLimit(moduleName,parentCode, -1, -1);
		return modules == null ? 0 : modules.size();
	}

	/**
	 * 搜索时统计模块数量
	 */
	@Override
	public Object searchModuleCount(String moduleName, LimitShowDTO limitShowDTO) {
		
		return menuMapperExtra.searchModuleCount(moduleName);
	}

	/**
	 * 通过menuId获取在menu表中获取对应一条数据
	 */
	@Override
	public Map<String, Object> getModuleObjectById(String menuId) {		
		return menuMapperExtra.getModuleObjectById(menuId);
	}
  
	/**
	 * 删除当前模块以及它的所有子模块
	 */
	@Override
	public boolean deleteByIdsAndChild(String[] menuIdList) {		
		return menuMapperExtra.deleteByIdsAndChild(menuIdList) > 0;
	}

	/**
	 * 修改
	 */
	@Override
	public boolean updateModuleObject(Menu menu) {
		
		return menuMapper.updateByPrimaryKeySelective(menu) > 0 ;
	}

	/**
     * 得到初始的模块列表
     */
	@Override
	public List<Map<String, Object>> getLoadList(Menu menu,
			LimitShowDTO limitShowDTO) {	
		return menuMapperExtra.getLoadList(menu.getMenuId(),menu.getLevel(),limitShowDTO.calculateStart(),limitShowDTO.calculateEnd());
	}

}
